package com.szsh.aiot.hsm.service.impl;

import com.google.gson.Gson;
import com.szsh.aiot.common.core.domain.AjaxResult;
import com.szsh.aiot.common.utils.TimeTools;
import com.szsh.aiot.hsm.domain.IFlowDiscern;
import com.szsh.aiot.hsm.domain.netprotect.INetprotectSwitch;
import com.szsh.aiot.hsm.domain.netprotect.NetDetailInfo;
import com.szsh.aiot.hsm.domain.netprotect.NetDetailModel;
import com.szsh.aiot.hsm.dto.enu.FlagType;
import com.szsh.aiot.hsm.dto.enu.FlowDiscernMaliciousType;
import com.szsh.aiot.hsm.mapper.IFlowDiscernMapper;
import com.szsh.aiot.hsm.mapper.INetprotectSwitchMapper;
import com.szsh.aiot.hsm.service.NetworkProtectionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @Description:网络防护Service
 * @Date 2023/8/25: 11:08
 * @Author: LOADING>>>>>(I_NETPROTECT_SWITCH)
 */


@Service
public class INetProtectSwitchServiceImpl implements NetworkProtectionService {

    private static final Logger LOGGER = LoggerFactory.getLogger(INetProtectSwitchServiceImpl.class);


    @Autowired
    private INetprotectSwitchMapper switchMapper;

    @Autowired
    private IFlowDiscernMapper flowDiscernMapper;


    @Override
    public AjaxResult getSwithState(String broadbandNO) {
        // 获取用户各个开关状态
        INetprotectSwitch switchStatus = switchMapper.selectINetprotectSwitchByBroadbandNO(broadbandNO);
        if (switchStatus != null) {
          return AjaxResult.success(switchStatus);
        }
        return AjaxResult.success("未查询到相关数据");
    }

    @Override
    public AjaxResult changeSwitchStatus(String broadbandNO, String swithType, String isOpen) {
        INetprotectSwitch switchStatus = switchMapper.selectINetprotectSwitchByBroadbandNO(broadbandNO);
        int dealResult = 0;
        if (switchStatus != null) {
            // 修改
            setFiledVal(switchStatus,swithType,Integer.parseInt(isOpen));
            dealResult =  switchMapper.updateINetprotectSwitch(switchStatus);
            if (dealResult ==0){
                return  new AjaxResult(AjaxResult.Type.ERROR,"处理异常");
            }
            return  new AjaxResult(AjaxResult.Type.SUCCESS,"处理成功");
        }
        return  new AjaxResult(AjaxResult.Type.ERROR,"未查询到相关开关数据");
    }

    @Override
    public AjaxResult getMaliciousInfo(String broadbandNO, String eventType) {

        NetDetailModel model = new NetDetailModel();

        if (!Objects.equals("All",eventType)){
            // 短信通知相关设置
           model = getSwithInfo(broadbandNO);

            // 详情信息
            List<NetDetailInfo> detailList = new ArrayList<>();

            List<IFlowDiscern> flowDiscerns = getFlowType(broadbandNO,eventType);

            if (flowDiscerns.isEmpty()) {
                return AjaxResult.success(model);
            }

            flowDiscerns.forEach(flow -> {
                NetDetailInfo detail = new NetDetailInfo();
                detail.setSerno(flow.getSerno());
                detail.setDevice(flow.getDeviceName());
                FlowDiscernMaliciousType flowDiscernMaliciousType = FlowDiscernMaliciousType.getMaliciosType(eventType);
                detail.setType(flowDiscernMaliciousType.getDesc());
                detail.setDesc(getDetail(flow));
                detail.setAccessTime(flow.getAccessTime());
                detailList.add(detail);
            });
            model.setDetails(detailList);
        }else{
            model = getSwithInfo(broadbandNO);

            // 详情信息
            List<NetDetailInfo> detailList = new ArrayList<>();

            List<String> eventTypeList = new ArrayList<>();
            eventTypeList.add("pishing");
            eventTypeList.add("virusFile");
            eventTypeList.add("cheatSite");
            eventTypeList.add("cheatSite");
            eventTypeList.add("fakeAd");
            eventTypeList.add("gambleSite");
            eventTypeList.add("gambleSite");
            eventTypeList.add("gambleSite");
            eventTypeList.add("breach");

            for (String type:eventTypeList){
                List<IFlowDiscern> flowDiscerns = getFlowType(broadbandNO,type);
                if (flowDiscerns.size() >0){
                    flowDiscerns.forEach(flow -> {
                        NetDetailInfo detail = new NetDetailInfo();
                        detail.setSerno(flow.getSerno());
                        FlowDiscernMaliciousType flowDiscernMaliciousType = FlowDiscernMaliciousType.getMaliciosType(type);
                        detail.setType(flowDiscernMaliciousType.getDesc());
                        detail.setDevice(flow.getDeviceName());
                        detail.setDesc(getDetail(flow));
                        detail.setAccessTime(flow.getAccessTime());
                        detailList.add(detail);
                    });
                    model.setDetails(detailList);
                }
            }
            }

        return AjaxResult.success(model);
    }

    /**
     * 短信通知相关设置
     * @param broadbandNO
     * @return
     */
    private NetDetailModel getSwithInfo(String broadbandNO){
        NetDetailModel model = new NetDetailModel();
        // 短信通知相关设置
        INetprotectSwitch switchStatus = switchMapper.selectINetprotectSwitchByBroadbandNO(broadbandNO);
        if (null != switchStatus) {
            String bindphone = switchStatus.getBindPhone();
            model.setPhoneflag(switchStatus.getShortMsgFlag() == FlagType.YES.getVal());
            if (!StringUtils.isEmpty(switchStatus.getBindPhone())) {
                model.setBindphone(bindphone);
                model.setDesensphone(bindphone.substring(0, 3) + "****"
                        + bindphone.subSequence(bindphone.length() - 4, bindphone.length()));
            }
        }
        return model;
    }


    private List<IFlowDiscern> getFlowType(String broadbandNO,String eventType){
        FlowDiscernMaliciousType type = FlowDiscernMaliciousType.getMaliciosType(eventType);

        // 用户删除的数据，不展示在网络防护详情页
        IFlowDiscern flowDiscern = new IFlowDiscern();
        flowDiscern.setBroadbandNO(broadbandNO);
        flowDiscern.setMaliciousType(type.getVal());
        flowDiscern.setDeleteflag(FlagType.NO.getVal());
        List<IFlowDiscern> flowDiscerns = flowDiscernMapper.selectIFlowDiscernList(flowDiscern);

        return flowDiscerns;
    }


    @Override
    public AjaxResult modBindPhone(String broadbandNO, String phone) {
        INetprotectSwitch switchStatus = switchMapper.selectINetprotectSwitchByBroadbandNO(broadbandNO);
        int dealResult = 0;
        if (switchStatus != null){
            // 修改
            switchStatus.setBroadbandNO(broadbandNO);
            switchStatus.setBindPhone(phone);
            dealResult =  switchMapper.updateINetprotectSwitch(switchStatus);
        }
        if (dealResult ==0){
            return  new AjaxResult(AjaxResult.Type.ERROR,"处理异常");
        }
        return  new AjaxResult(AjaxResult.Type.SUCCESS,"处理成功");
    }

    @Override
    public AjaxResult BindPhone(String broadbandNO, String phone) {

        INetprotectSwitch switchStatus = switchMapper.selectINetprotectSwitchByBroadbandNO(broadbandNO);
        int dealResult = 0;
        if (switchStatus == null) {
            // 新增
            switchStatus = new INetprotectSwitch();
            switchStatus.setBroadbandNO(broadbandNO);
            switchStatus.setBindPhone(phone);
            switchStatus.setShortMsgFlag(FlagType.YES.getVal());
            dealResult = switchMapper.insertINetprotectSwitch(switchStatus);
        }else{
            if (org.apache.commons.lang3.StringUtils.isNotBlank(switchStatus.getBindPhone())){
                return  new AjaxResult(AjaxResult.Type.ERROR,"已存在绑定关系");
            }else{
                switchStatus = new INetprotectSwitch();
                switchStatus.setBroadbandNO(broadbandNO);
                switchStatus.setBindPhone(phone);
                switchStatus.setShortMsgFlag(FlagType.YES.getVal());
                dealResult = switchMapper.updateINetprotectSwitch(switchStatus);
            }
        }
        if (dealResult ==0){
            return  new AjaxResult(AjaxResult.Type.ERROR,"处理异常");
        }
        return  new AjaxResult(AjaxResult.Type.SUCCESS,"处理成功");
    }

    @Override
    public AjaxResult unBindPhone(String broadbandNO, String phone) {

        int dealResult = 0;
        INetprotectSwitch query = new INetprotectSwitch();
        query.setBindPhone(phone);
        query.setBroadbandNO(broadbandNO);
        INetprotectSwitch switchStatusGet = switchMapper.selectINetprotectSwitchByAccount(broadbandNO,phone);
        if (switchStatusGet != null){
            INetprotectSwitch   switchStatus = new INetprotectSwitch();
            switchStatus.setBroadbandNO(broadbandNO);
            switchStatus.setBindPhone("");
            switchStatus.setShortMsgFlag(FlagType.NO.getVal());
            switchStatus.setModTime(new Date());
            dealResult = switchMapper.updateINetprotectSwitch(switchStatus);
            if (dealResult ==0){
                return  AjaxResult.error("处理失败");
            }
            return  AjaxResult.success("处理成功");
        }
        return  AjaxResult.error("未查询到相关绑定关系");
    }

    @Override
    public AjaxResult getBindPhone(String broadbandNO) {
        INetprotectSwitch switchStatus = switchMapper.selectINetprotectSwitchByBroadbandNO(broadbandNO);
        if (switchStatus != null){
            String phone = switchStatus.getBindPhone();
            if (!StringUtils.isEmpty(phone)){
                Map phoneMap = new HashMap<>();
                phoneMap.put("phone",phone);
                return AjaxResult.success("查询成功",phoneMap);
            }
            return AjaxResult.badRequest("查询绑定账号为空");
        }
        return AjaxResult.badRequest("未查询到相关绑定数据");
    }

    @Override
    public AjaxResult getNumByMaliciousType(String broadbandNO, int type) {
        int count = 0;
        try {
            String yesToday = TimeTools.date2String(TimeTools.plusDays(-1), "yyyy-MM-dd");
            count = flowDiscernMapper.getAllCountByTime(broadbandNO, type, yesToday);
        } catch (Exception e) {
            LOGGER.error("查询放欺诈数据异常", e);
           return AjaxResult.error("数据处理异常");
        }
        return AjaxResult.success("数据处理成功",count);
    }

    @Override
    public AjaxResult delete(String broadbandNO, String page, List<String> sernoList) {

        FlowDiscernMaliciousType type = FlowDiscernMaliciousType.getMaliciosType(page);
        int delRet = 0;

        for (String serNo: sernoList){
            IFlowDiscern iFlowDiscern = new IFlowDiscern();
            iFlowDiscern.setBroadbandNO(broadbandNO);
            iFlowDiscern.setMaliciousType(type.getVal());
            iFlowDiscern.setSerno(serNo);
            iFlowDiscern.setDeleteflag(1);
            LOGGER.info("更新参数为{}",new Gson().toJson(iFlowDiscern));
            delRet = flowDiscernMapper.updateIFlowDiscern(iFlowDiscern);

            if (delRet == 0){
                return AjaxResult.error("处理异常");
            }
        }
        return AjaxResult.success("处理成功");
    }

    /**
     * 根据页面防火墙类型填充对象的相关属性
     *
     * @param switchStatus
     * @param
     * @param isOpen
     */
    private void setFiledVal(INetprotectSwitch switchStatus, String switchname, int isOpen) {
        try {
            // 总开关修改
            if (FlowDiscernMaliciousType.ALL.getPage().equals(switchname)) {
                switchStatus.setPishingFlag(isOpen);
                switchStatus.setVirusFileFlag(isOpen);
                switchStatus.setCheatSiteFlag(isOpen);
                switchStatus.setFakeAdFlag(isOpen);
                switchStatus.setGambleSiteFlag(isOpen);
                switchStatus.setBreachFlag(isOpen);
                switchStatus.setModTime(TimeTools.getNow());
            } else {
                if (Objects.equals(switchname,"pishingFlag")){
                    switchStatus.setPishingFlag(isOpen);
                }
                if (Objects.equals(switchname,"virusFileFlag")){
                    switchStatus.setVirusFileFlag(isOpen);
                }
                if (Objects.equals(switchname,"cheatSiteFlag")){
                    switchStatus.setCheatSiteFlag(isOpen);
                }
                if (Objects.equals(switchname,"fakeAdFlag")){
                    switchStatus.setFakeAdFlag(isOpen);
                }
                if (Objects.equals(switchname,"gambleSiteFlag")){
                    switchStatus.setGambleSiteFlag(isOpen);
                }
                if (Objects.equals(switchname,"breachFlag")){
                    switchStatus.setBreachFlag(isOpen);
                }
                if (Objects.equals(switchname,"shortMsgFlag")){
                    switchStatus.setShortMsgFlag(isOpen);
                }
                switchStatus.setModTime(TimeTools.getNow());
            }
        } catch (Exception e) {
            LOGGER.error("用户修改开关状态失败", e);
        }
    }

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        Class clazz = Class.forName("com.szsh.aiot.hsm.domain.netprotect.INetprotectSwitch");

        Field[] fields1 = clazz.getDeclaredFields();

        for (Field f1 : fields1) {
            f1.setAccessible(true);
            if(f1.getName().equals("virusFileFlag"))
                continue;
            Object value = f1.get(clazz);
            f1.set(clazz,1);
            }
        System.out.println("field"+new Gson().toJson(clazz));
        }




    /**
     * 根据页面防火墙类型填充对象的相关属性
     *
     * @param switchStatus
     * @param filed
     */
    private int getFiledVal(String filed, INetprotectSwitch switchStatus) {
        if (switchStatus == null) {
            return 0;
        }
        try {
            String firstChar = filed.substring(0, 1);
            String methodName = "get" + firstChar.toUpperCase() + filed.substring(1) + "Flag";
            Class<?> cls = Class.forName(INetprotectSwitch.class.getName());
            Method method = cls.getMethod(methodName);
            return (Integer) method.invoke(switchStatus);
        } catch (Exception e) {
            LOGGER.error("获取用户开关状态失败", e);
            return 0;
        }
    }


    /**
     * 事件详情描述
     *
     * @param flowDiscern
     * @return
     */
    private String getDetail(IFlowDiscern flowDiscern) {
        FlowDiscernMaliciousType maliciousType = FlowDiscernMaliciousType
                .getMaliciosByType(flowDiscern.getMaliciousType());
        // 非失陷
        if (FlowDiscernMaliciousType.BREACH.getVal() != maliciousType.getVal()) {
            return String.format(maliciousType.getDetail(), flowDiscern.getUri());
        }
        String breachInfo = flowDiscern.getTypeDesc();
        if (!StringUtils.isEmpty(breachInfo) && breachInfo.contains("、")) {
            return String.format(maliciousType.getDetail(), "可能", breachInfo);
        } else {
            return String.format(maliciousType.getDetail(), "", breachInfo);
        }
    }

}
